# coding: utf-8

from comm_utils import *


class Crontab:

    strict = False
    minute = hours = days = months = curr_month_days = weeks = None

    def __init__(self, _cron_str, _strict=False):
        self.cron = _cron_str
        self.strict = _strict
        self.order = [self.minute, self.hours, self.days, self.months, self.weeks] = self.cron.split(" ")
        self.cc = self.cron_format()
        # self.cron_format()

    def next_time(self):
        return self.cc.next()

    def delay_time(self):
        return time_to_delay(self.cc.next())

    def cron_format(self):
        _it = time.localtime()
        _year, _mon, _day, _hour, _min, _sec, _wday, _yday, _isdst = (
            _it.tm_year, _it.tm_mon, _it.tm_mday, _it.tm_hour, _it.tm_min, _it.tm_sec, _it.tm_wday, _it.tm_yday, _it.tm_isdst
        )
        self.minute = loop_generator(
            Crontab.get_cron_part_format_info(self.minute, 59), initial=_it.tm_min, notice_end=True, near_by=True)
        self.hours = loop_generator(
            Crontab.get_cron_part_format_info(self.hours, 23), initial=_it.tm_hour, notice_end=True, near_by=True)
        self.days = loop_generator(
            Crontab.get_cron_part_format_info(self.days, 31, 1), initial=_it.tm_mday, notice_end=True, near_by=True)
        self.months = loop_generator(
            Crontab.get_cron_part_format_info(self.months, 12, 1), initial=_it.tm_mon, notice_end=True, near_by=True)

        self.weeks = Crontab.get_cron_part_format_info(self.weeks, 6)
        self.curr_month_days = get_current_month_days(_year, _mon)

        # for a in range(4):
        #     print self.minute.next()
        #     print self.hours.next()
        #     print self.days.next()
        #     print self.months.next()
        #     print self.weeks
        # return

        _sec = 0
        _hour = self.hours.next()
        _day = self.days.next()
        _mon = self.months.next()

        while True:

            _min = self.minute.next()

            if not _min:
                _min = self.minute.next()
                _hour = self.hours.next()

            if not _hour:
                _hour = self.hours.next()
                _day = self.days.next()

            if not _day:
                _day = self.days.next()
                _mon = self.months.next()

            if not _mon:
                _mon = self.months.next()
                _year += 1

            if _day > self.curr_month_days:
                while self.days.next():
                    pass
                _day = None
                continue

            _wday = get_weekday_by_ymd(_year, _mon, _day) - 1
            if _wday not in self.weeks:
                _day = self.days.next()
                continue

            # print time.strptime("%d-%d-%d %d:%d:%d" % (_year, _mon, _day, _hour, _min, _sec), "%Y-%m-%d %H:%M:%S")
            yield time.strptime("%d-%d-%d %d:%d:%d" % (_year, _mon, _day, _hour, _min, _sec), "%Y-%m-%d %H:%M:%S")

    @staticmethod
    def get_cron_part_format_info(_str, _length, _start=0):
        _regex_res = re.match(r'(?:(^\d$)|(\d+-\d+)|((?:\d+,?)+)|(\*))(?:/(\d+))?', _str)
        _cron_attr = [_regex_res.group(i) for i in range(0, 6)]
        _step = int(_cron_attr[5]) if _cron_attr[5] else 1

        res_range = []
        if _cron_attr[1]:
            res_range = [int(_cron_attr[1])]
        elif _cron_attr[2]:
            res_range = range2(*[int(x) for x in (_cron_attr[2]+"-%s" % _step).split('-')])
        elif _cron_attr[3]:
            res_range = [int(x) for x in _cron_attr[3].split(',') if x != ""]
        elif _cron_attr[4]:
            res_range = range2(_start, _length, _step)
        else:
            pass

        return sorted(res_range)

if __name__ == '__main__':
    c = Crontab("50/2 2-4 * * *")
    print c.delay_time()
    print c.delay_time()
    print c.delay_time()
    print c.delay_time()
    print c.delay_time()



